(function webpackUniversalModuleDefinition(root, factory) {
    if (typeof exports === 'object' && typeof module === 'object') {
        module.exports = factory();
    } else if (typeof define === 'function' && define.amd)
        define([], factory);
    else
        root["LyVerify"] = factory();
})(this, function () {
    //实现一个简单的 jquery 包含jquery 的主要方法 刚好够用
    var SQ = function (selectorOrArray) {
        let elements;
        if (typeof selectorOrArray === 'string') {
            var m = selectorOrArray.trim().substr(0,1);
           if(m === '<'){
               var item=  document.createElement("div");
               item.innerHTML=selectorOrArray;
               var child= item.children[0];
               child .remove();
               elements = [child];
           } else{
               elements = document.querySelectorAll(selectorOrArray);
           }
        } else if (selectorOrArray instanceof Array) {
            elements = selectorOrArray;
        }else if (selectorOrArray instanceof Object) {
            elements = [selectorOrArray];
        }
        function getStyle(obj, arr) {
            if (obj.currentStyle) {
                return obj.currentStyle[arr];  //针对ie
            } else {
                return document.defaultView.getComputedStyle(obj, null)[arr];
            }
        }

        var pxKey=['left','margin','top','right','bottom','padding','margin-left','margin-top','margin-right','margin-bottom'];

        function fixPx(key,v){
            if(pxKey.indexOf(key)>-1){
                return parseInt(v)+'px';
            }
            return v;
        }
        return {
            length:elements.length,
            el:elements[0],
            append:function (item){
                if(item.el){
                    item=item.el;
                }
                elements[0].append(item);
            },
            position(){
                var item=elements[0];
                return {
                    left:item.offsetLeft,
                    top:item.offsetTop
                }
            },
            offset(){
                var item = elements[0];
                function getTop(e){
                    var offset=e.offsetTop;
                    if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
                    return offset;
                }
                function getLeft(e){
                    var offset=e.offsetLeft;
                    if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
                    return offset;
                }
                return {
                    left:getLeft(item),
                    top:getTop(item),
                }
            },
            parent(selector){
               if(!selector){
                   return elements[0].parentNode?SQ(elements[0].parentNode):[];
               }else{
                  var ps = document.querySelectorAll(selectorOrArray);
                  function getParent(item){
                    var p = item.parentNode;
                    if(ps.indexOf(p)>-1){
                        return SQ(elements[0].parentNode);
                    }
                    if(p.nodeName!=='BODY'){
                        return getParent(p);
                    }
                  }
                 return getParent(elements[0]);
               }
            },
            find(selector) {
                let array = [];
                //创建一个临时素组来存储elements这个伪数组
                for (let i = 0; i < elements.length; i++) {
                    const elements2 = Array.from(elements[i].querySelectorAll(selector));
                    array = array.concat(elements2);
                }
                array.oldApi = this;
                return SQ(array);
            },
            show:function (){
                for (let i = 0; i < elements.length; i++) {
                    var display = elements[i].style.display;
                    if(display ==='none'){
                        elements[i].style.display='';
                    }
                    display=getStyle(elements[i],'display')
                    if(display === 'none'){
                        elements[i].style.display='block';
                    }
                }
            },
            hide:function (){
                this.css({'display':'none'})
            },
            fadeIn:function (){
                this.show();
                this.css({'opacity':'0'})
                this.animate({
                      opacity:1
                  },200)
            },
            fadeOut:function (){
                var me=this;
                this.css({'opacity':'1'})
                this.animate({
                    opacity:0
                },200,'',function (){
                    me.css({'display':'none'})
                });
            },
            on(event, fun) {
                var es = event.split(' ');
                for (let i = 0; i < elements.length; i++) {
                    for (let j = 0; j < es.length; j++) {
                        var e = es[j];
                        if (!e) {
                            continue;
                        }
                        var ele = elements[i];
                        (function (ele){
                            var call=function () {
                                fun.apply(ele,arguments);
                            };
                            if(!ele['events_'+e]){
                                ele['events_'+e]=[];
                            }
                            ele['events_'+e].push(call);
                            ele.addEventListener(e,call)
                        })(ele);
                    }
                }
            },
            off(event,fun) {
                var es = event.split(' ');
                for (let i = 0; i < elements.length; i++) {
                    for (let j = 0; j < es.length; j++) {
                        var e = es[j];
                        if (!e) {
                            continue;
                        }
                        var ele = elements[i];
                        (function (ele){
                            if(!ele['events_'+e]){
                                ele['events_'+e]=[];
                            }
                            for(var m =0;m<ele['events_'+e].length;m++){
                                var call=ele['events_'+e][m];
                                if(fun){
                                    if(call!==fun){
                                        continue;
                                    }
                                }
                                ele.removeEventListener(e,call)
                            }
                        })(ele);
                    }
                }
            },
            slideDown() {
                this.show();
                var height=this.css('height');
                var padding= parseInt(this.css('padding-top'))+parseInt( this.css('padding-bottom'));
                this.css({
                    height:padding+'px'
                });
                this.animate({
                    height:height
                });
            },
            slideUp() {
                var me=this;
                var padding= parseInt(this.css('padding-top'))+parseInt( this.css('padding-bottom'));
                this.animate({
                    height:padding+'px'
                },null,'',function (){
                    me.css({'display':'none','height':''});

                });
            },
            remove() {
                for (let i = 0; i < elements.length; i++) {
                    elements[i].remove();
                }
            },
            text(text) {
                if (text) {
                    for (let i = 0; i < elements.length; i++) {
                        elements[i].innerText = text;
                    }
                } else {
                    elements[0].innerText = text;
                }
            },
            animate(json, time,easing,callback) {
                if(!time){
                    time=100;
                }
                var sp=10/time;
                for (let i = 0; i < elements.length; i++) {
                    var obj = elements[i];
                    if (obj.timer) {
                        clearInterval(obj.timer);
                    }
                    obj.timer = setInterval(function () {
                        var flag = true;
                        for (var arr in json) {
                            var val = parseInt(json[arr]);
                            if(arr==='left'){
                            }
                            var icur = 0;
                            if (arr === "opacity") {
                                val=val*100;
                                icur = Math.round(parseFloat(getStyle(obj, arr)) * 100);
                            } else {
                                icur = parseInt(getStyle(obj, arr));
                            }
                            var speed = (val - icur) * sp;
                            speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                            if (icur !==val) {
                                flag = false;
                            }
                            if (arr === "opacity") {
                                obj.style.filter = "alpha(opacity : "+(icur + speed)+" )";
                                obj.style.opacity = (icur + speed) / 100;
                            } else {
                                obj.style[arr] = icur + speed + "px";
                            }
                        }
                        if (flag) {
                            clearInterval(obj.timer);
                            if(callback){
                                callback();
                            }
                        }
                    }, 10);
                }
            },
            attr(k, v) {
                if (v) {
                    for (let i = 0; i < elements.length; i++) {
                        var element = elements[i];
                        element.setAttribute(k, v);
                    }
                } else {
                    if (elements.length < 1) {
                        return null;
                    }
                    return elements[0].getAttribute(k);
                }
            },
            css(obj, v1) {
                if (typeof obj === 'string') {
                    if (elements.length < 1) {
                        return this;
                    }
                    if (v1 == null) {
                        return getStyle(elements[0], obj)
                    }
                    var key=obj;
                    obj={};
                    obj[key]=v1;
                }
                for (let i = 0; i < elements.length; i++) {
                    for (var k in obj) {
                        elements[i].style[k] =  fixPx(k,obj[k]);
                        if(k==='opacity'){
                            elements[i].style.filter = "alpha(opacity : "+parseInt(obj[k])*100+" )";
                        }
                    }
                }
                return this;
            },
            width:function (){
                return parseInt(this.css('width'));
            },height:function (){
                return parseInt(this.css('height'));
            },
            removeClass(className) {
                for (let i = 0; i < elements.length; i++) {
                    elements[i].classList.remove(className);
                }
                return this;
            },
            addClass(className) {
                for (let i = 0; i < elements.length; i++) {
                    elements[i].classList.add(className);
                }
                return this;
            }
        };
    };
    SQ.extend=function (k,v){
        return  Object.assign(k,v);
    }
    SQ.get = function (url,call){
        var request = null;
        if (window.XMLHttpRequest) {
            request = new XMLHttpRequest();//W3C
        } else {
            request = new ActiveXObject('MicroSoft.XMLHTTP');//IE
        }
        request.open('get', url);
        request.onreadystatechange = function () {
            if (request.readyState === 4 && request.status === 200) {
                var val = request.responseText;
                var type = request.getResponseHeader('content-type');
                if(type.indexOf('json')>0){
                    val = JSON.parse(val);
                }
                call(val);
            }
            if (request.readyState === 4 && (request.status >= 400)) {
            }
        };
        request.onerror = function (e) {
        };
        request.send();
    };
    SQ.post = function (url,obj,call){
        var request = null;
        if (window.XMLHttpRequest) {
            request = new XMLHttpRequest();//W3C
        } else {
            request = new ActiveXObject('MicroSoft.XMLHTTP');//IE
        }
        request.open('POST', url,true);
        request.onreadystatechange = function () {
            if (request.readyState === 4 && request.status === 200) {
                var val = request.responseText;
                var type = request.getResponseHeader('content-type');
                if(type.indexOf('json')>0){
                    val = JSON.parse(val);
                }
                call(val);
            }
            if (request.readyState === 4 && (request.status >= 400)) {
            }
        };
        request.onerror = function (e) {
        };
        request.setRequestHeader("Content-Type"
            , "application/json");
        request.send(JSON.stringify(obj));
    };



    var LyVerify = {
        slide: function (conf) {
            var config = {

                codeUrl: '/home/testcode',
                checkUrl: '/home/testcheck',
                senseUrl: '/home/senseCheck',
                sense: false,
                sense_scene: '',
                sense_ok: true,
                checkParams: function () {
                    return {}
                },
                type: 'slide',
                hidePanel: false,
                fail: function (rs) {
                }, success: function (rs) {
                }
            }
            config = Object.assign(config, conf);
            if (config.sense && config.sense_ok) {
                return intellisense(config);
            }
            var $model = SQ("<div class='ly-model-bg'></div>");
            $model.on('click', function () {
                $panel.fadeOut();
                $model.fadeOut();
            })
            var panelHtml = '<div class="lyz-box"><div class="lyz-img-box"><div class="lyz-img-warp" style="position: relative"><img class="lyz-box-img-bg"/><img class="lyz-box-item"/><div class="lyz-box-loading" style="display:none;"><div class="lyz-box-loading-icon"></div><span>加载中</span></div><div class="lyz-box-message">请按要求处理</div> <div class="lyz-box-tool"><div class="lyz-box-refresh"></div></div></div></div><div class="lyz-move-box"><div class="lyz-moved"></div><div class="lyz-move-ctrl" style="left: -1px"><span class="lyz-move-icon"></span></div><span class="lyz-move-text">向右拖动滑块填充拼图</span></div></div>';
            var $panel = null;
            $panel = SQ(panelHtml);
            var sign_key = '';
            var itemMd5 = '';
            var begin_time = 0;
            var $ctrl = $panel.find('.lyz-move-ctrl');
            var $imgBox = $panel.find('.lyz-img-box');
            var $moved = $panel.find('.lyz-moved');
            var $box = $panel.find('.lyz-move-box');
            var $item = $panel.find('.lyz-box-item');
            var $img = $panel.find('.lyz-box-img-bg');
            var $refresh = $panel.find('.lyz-box-refresh');
            var $loading = $panel.find('.lyz-box-loading');
            var $message = $panel.find('.lyz-box-message');
            var is_success = false;
            var _sid = '';
            $refresh.on('click', function () {
                if (is_success) {
                    return;
                }
                loadVerify();
            });

            function showMessage(success, msg) {
                $message.slideDown();
                $message.text(msg);
                if (success) {
                    $message.removeClass('lyz-box-message-error');
                } else {
                    $message.addClass('lyz-box-message-error');
                }
                setTimeout(function () {
                    $message.slideUp();
                }, 2000);
            }

            function mouseUp() {
                if (is_success) return;
                $box.off('touchmove mousemove');
                var time = new Date().getTime() + '';
                var code = a(itemMd5 + time + $item.position().left + '', sign_key);
                var did = devid();
                var check = a(encodeURIComponent(JSON.stringify(config.checkParams())), did);
                check = randomStr(16) + check + randomStr(16);
                var params = {
                    _did: did,
                    _sid: _sid,
                    sense: config.sense,
                    verify_code: code,
                    verify_check: check
                };
                SQ.post(config.checkUrl, params, function (rs) {
                    rs._sid = _sid;
                    $box.removeClass('lyz-moving');
                    if (!rs.success) {
                        showMessage(false, rs.msg ? rs.msg : '验证失败,请重新操作');
                        if (config.fail) {
                            config.fail(rs);
                        }
                        var animTime = 500;
                        $box.addClass('lyz-move-error');
                        $ctrl.animate({left: "-1px"}, animTime);
                        $moved.animate({'width': '0'}, animTime);
                        $item.animate({left: 0}, animTime);
                        setTimeout(function () {
                            $box.removeClass('lyz-move-error');
                            loadVerify();
                            if(config.hidePanel&&config.container){
                                $imgBox.css({display:''});
                            }
                        }, animTime);
                    } else {
                        is_success = true;
                        showMessage(true, rs.msg ? rs.msg : ('恭喜你,验证成功'));
                        if (config.success) {
                            config.success(rs);
                        }
                        if (config.sense) {
                            localStorage.setItem('lyv_sense_token' + config.sense_scene, rs.token);
                        }
                        $box.addClass('lyz-move-success');
                        if (!config.container) {
                            setTimeout(function () {
                                $panel.fadeOut();
                                $model.fadeOut();
                            }, 1000);
                        }
                    }
                });
            }

            function loadVerify() {
                if (is_success) return;
                $loading.fadeIn();
                _sid = randomStr();
                var url = config.codeUrl;
                if (url.indexOf('?') === -1) {
                    url += "?";
                }
                url += "&_sid=" + _sid;
                SQ.get(url, function (rs) {
                    var code = rs.code;
                    var kv = code.split(' ');
                    sign_key = kv[0].substr(0, 16) + kv[1].substr(0, 16);
                    $img.attr('src', b(kv[0].substr(16), sign_key));
                    $item.attr('src', b(kv[1].substr(16), sign_key));
                    var y = kv[2].substr(32);
                    itemMd5 = kv[2].substr(0, 32);
                    $item.css({top: y + 'px'})
                    begin_time = new Date().getTime();
                    $loading.fadeOut();
                });
            }


            $ctrl.on('touchstart mousedown', function (e) {
                if (is_success) return;
                // 鼠标按下后就要取到当前元素的x、y的位置数据
                var x = e.pageX || e.targetTouches[0].pageX;
                // 取到了x和y的坐标对象
                var divx = $ctrl.position().left;
                $box.addClass('lyz-moving');
                if(config.hidePanel&&config.container){
                    $imgBox.show();
                }
                // 绑定一个鼠标移动的事件
                $box.on('touchmove mousemove', function (event) {
                    // 鼠标移动时 取当前移动后的x、y的数据
                    var x2 = event.pageX || event.targetTouches[0].pageX;
                    var left = divx + (x2 - x);
                    if (left < -1) {
                        left = -1;
                    }
                    if (left > 246) {
                        left = 246;
                    }
                    $item.css({left: (left + 1) + 'px'});
                    $moved.css({'width': (left + 1) + 'px'})
                    $ctrl.css({
                        left: left + "px"
                    });
                });
            });
            $ctrl.on('touchend mouseup', mouseUp);


            if (config.container) {
                SQ(config.container).append($panel);
                if (config.hidePanel) {
                    $panel.addClass('lyz-box-trigger');
                    $panel.css({
                        width: '288px',
                        display: 'block',
                        position: 'relative',
                        border: 'none',
                        padding: 0
                    });
                    $imgBox.css({
                        position: 'absolute',
                        bottom: '40px',
                        'padding-bottom': '6px'
                    });
                } else {
                    $panel.css({
                        width: '308px',
                        display: 'block',
                        position: 'initial'
                    });
                }
                loadVerify();
            }else{
                $panel.addClass('lyz-box-pop');
            }
            return {
                reset: function () {
                    is_success = false;
                    $box.removeClass('lyz-move-success');
                    $ctrl.css({left: "-1px"});
                    $moved.css({'width': '0'});
                    $item.css({left: 0});
                    loadVerify();
                },
                show: function (el) {
                    if ($model.parent().length === 0) {
                        SQ(document.body).append($model);
                    }
                    if ($panel.parent().length === 0) {
                        SQ(document.body).append($panel);
                    }
                    if (el && window.innerWidth > 600) {
                        var $el = SQ(el);
                        var offset = $el.offset();
                        var top = offset.top - window.scrollY - 110;
                        var left = offset.left - 60;
                        if (top < 10) {
                            top = 10;
                        }
                        if (left < 10) {
                            left = 10;
                        }
                        if (left + 310 > window.innerWidth) {
                            left = window.innerWidth - 320;
                        }
                        $panel.css({
                            top: top+'px',
                            left: left+'px'
                        })
                    }
                    $panel.fadeIn();
                    $model.fadeIn();
                    loadVerify();
                },
                hide: function () {
                    $panel.fadeOut();
                    $model.fadeOut();
                    setTimeout(function () {
                        $panel.remove();
                        $model.remove();
                    }, 1000);
                }
            }
        },
        text: function (conf) {
            var config = {
                codeUrl: '/home/testcode',
                checkUrl: '/home/testcheck',
                senseUrl: '/home/senseCheck',
                sense: false,
                sense_scene: '',
                sense_ok: true,
                size: 3,
                type: 'text',
                hidePanel: false,
                checkParams: function () {
                    return {}
                },
                fail: function (rs) {
                }, success: function (rs) {
                }
            }
            SQ.extend(config, conf);
            if (config.sense && config.sense_ok) {
                return intellisense(config);
            }
            var $model = SQ("<div class='ly-model-bg'></div>");
            $model.on('click', function () {
                $panel.fadeOut();
                $model.fadeOut();
            })
            var panelHtml = '<div class="lyz-box"> <div class="lyz-img-box"> <div class="lyz-img-warp" style="position: relative"><img class="lyz-box-img-bg"/><div class="lyz-box-loading" style="display:none;"><div class="lyz-box-loading-icon"></div><span>加载中</span></div><div class="lyz-box-message">请按要求处理</div> <div class="lyz-box-tool"><div class="lyz-box-refresh"></div></div></div></div><div class="lyz-box-pick" ><div class="lyz-box-pick-click"  ><span class="lyz-box-pick-icon"></span><span class="lyz-box-pick-text">立即点击验证</span></div><div class="lyz-box-pick-tip" style=""><span >请依次点击</span><img  class="lyz-box-pick-tip-img" src=""/></div><div class="lyz-pick-success-warp"  ><span class="lyz-pick-success-icon"></span><span class="lyz-pick-success-text">验证成功</span></div></div></div>';
            var $panel = null;
            $panel = SQ(panelHtml);
            var result = [];
            var sign_key = '';
            var begin_time = 0;
            var $imgWarp = $panel.find('.lyz-img-warp');
            var $imgBox = $panel.find('.lyz-img-box')
            var $tip_img = $panel.find('.lyz-box-pick-tip-img');
            var $img = $panel.find('.lyz-box-img-bg');
            var $refresh = $panel.find('.lyz-box-refresh');
            var $box = $panel.find('.lyz-box-pick');
            var $loading = $panel.find('.lyz-box-loading');
            var $message = $panel.find('.lyz-box-message');
            var is_success = false;
            var _sid = '';

            $refresh.on('click', function () {
                if (is_success) {
                    return;
                }
                loadVerify();
            });

            function showMessage(success, msg) {
                $message.slideDown();
                $message.text(msg);
                if (success) {
                    $message.removeClass('lyz-box-message-error');
                } else {
                    $message.addClass('lyz-box-message-error');
                }
                setTimeout(function () {
                    $message.slideUp();
                }, 2000);
            }

            function checkResult() {
                if (is_success) return;
                var code = result.join(' ');
                var did = devid();
                var check = a(encodeURIComponent(JSON.stringify(config.checkParams())), did);
                check = randomStr(16) + check + randomStr(16);
                var params = {
                    _did: did,
                    _sid: _sid,
                    sense: config.sense,
                    verify_code: code,
                    verify_check: check
                };
                SQ.post(config.checkUrl, params, function (rs) {
                    rs._sid = _sid;
                    if (!rs.success) {
                        showMessage(false, rs.msg ? rs.msg : '验证失败,请重新操作');
                        if (config.fail) {
                            config.fail(rs);
                        }
                        loadVerify();
                    } else {
                        is_success = true;
                        showMessage(true, rs.msg ? rs.msg : ('恭喜你,验证成功'));
                        if (config.success) {
                            config.success(rs);
                        }
                        if (config.sense) {
                            localStorage.setItem('lyv_sense_token' + config.sense_scene, rs.token);
                        }
                        $box.addClass('lyz-pick-success');
                        if (!config.container) {
                            setTimeout(function () {
                                $panel.fadeOut();
                                $model.fadeOut();
                            }, 1000);
                        }
                    }
                });
            }

            $img.on('click',function (event) {
                if (result.length + 1 > config.size) {
                    return;
                }
                var x = event.offsetX;
                var y = event.offsetY;
                var w = $img.width();
                var h = $img.height();
                var p1 = x / w * 10000000000000000;
                var p2 = y / h * 10000000000000000;
                result.push(a(p1 + '', sign_key) + ' ' + a(p2 + '', sign_key));
                var m = '<div mark-show-index="' + result.length + '" class="lyz-pick-item" style="left: ' + (x - 12) + 'px; top: ' + (y - 12) + 'px; transform: translateZ(0px);"><div class="lyz-pick-item-no">' + result.length + '</div></div>';
                m = SQ(m);
                $imgWarp.append(m);
                m.on('click',function (e) {
                    e.preventDefault();
                    if (is_success) {
                        return;
                    }
                    var id = SQ(this).attr('mark-show-index');
                    for (var i = id; i <= config.size; i++) {
                        $panel.find('.lyz-pick-item[mark-show-index=' + i + ']').remove();
                    }
                    result.length = id - 1;
                });
                if (result.length === config.size) {
                    checkResult();
                }
            });

            function loadVerify() {
                if (is_success) return;
                $loading.fadeIn();
                _sid = randomStr();
                var url = config.codeUrl;
                if (url.indexOf('?') === -1) {
                    url += "?";
                }
                url += "&_sid=" + _sid;
                SQ.get(url, function (rs) {
                    var code = rs.code;
                    var kv = code.split(' ');
                    sign_key = kv[0].substr(0, 16) + kv[1].substr(0, 16);
                    $img.attr('src', b(kv[0].substr(16), sign_key));
                    $tip_img.attr('src', b(kv[1].substr(16), sign_key));
                    $panel.find('.lyz-pick-item').remove();
                    result.length = 0;
                    begin_time = new Date().getTime();
                    $loading.fadeOut();
                });
            }


            if (config.container) {
                SQ(config.container).append($panel);
                if (config.hidePanel) {
                    $panel.addClass('lyz-box-trigger');
                    $panel.css({
                        width: '288px',
                        display: 'block',
                        position: 'relative',
                        border: 'none',
                        padding: 0
                    });
                    $imgBox.css({
                        position: 'absolute',
                        bottom: '40px',
                        'padding-bottom': '6px'
                    });
                } else {
                    $panel.css({
                        width: '308px',
                        display: 'block',
                        position: 'initial'
                    });
                }
                loadVerify();
            }else{
                $panel.addClass('lyz-box-pop');
            }
            return {
                reset: function () {
                    is_success = false;
                    $box.removeClass('lyz-pick-success');
                    loadVerify();
                },
                show: function (el) {
                    if ($model.parent().length === 0) {
                        SQ(document.body).append($model);
                    }
                    if ($panel.parent().length === 0) {
                        SQ(document.body).append($panel);
                    }
                    if (el && window.innerWidth > 600) {
                        var $el = SQ(el);
                        var offset = $el.offset();
                        var top = offset.top - window.scrollY - 110;
                        var left = offset.left - 60;
                        if (top < 10) {
                            top = 10;
                        }
                        if (left < 10) {
                            left = 10;
                        }
                        if (left + 310 > window.innerWidth) {
                            left = window.innerWidth - 320;
                        }
                        $panel.css({
                            top: top+'px',
                            left: left+'px'
                        })
                    }
                    $panel.fadeIn();
                    $model.fadeIn();
                    loadVerify();
                },
                hide: function () {
                    $panel.fadeOut();
                    $model.fadeOut();
                    setTimeout(function () {
                        $panel.remove();
                        $model.remove();
                    }, 1000);
                }
            }
        },
        move: function (conf) {
            var config = {
                codeUrl: '/home/testcode',
                checkUrl: '/home/testcheck',
                senseUrl: '/home/senseCheck',
                sense: false,
                sense_scene: '',
                sense_ok: true,
                type: 'move',
                hidePanel: false,
                checkParams: function () {
                    return {}
                },
                fail: function (rs) {
                }, success: function (rs) {
                }
            }
            SQ.extend(config, conf);
            if (config.sense && config.sense_ok) {
                return intellisense(config);
            }
            var $model = SQ("<div class='ly-model-bg'></div>");
            $model.on('click', function () {
                $panel.fadeOut();
                $model.fadeOut();
            })
            var panelHtml = '<div class="lyz-box"> <div class="lyz-img-box"><div class="lyz-img-warp" style="position: relative"><img class="lyz-box-img-move" /><img class="lyz-box-img-bg"/><div class="lyz-box-loading" style="display:none;"><div class="lyz-box-loading-icon"></div><span>加载中</span></div><div class="lyz-box-message">请按要求处理</div> <div class="lyz-box-tool"><div class="lyz-box-refresh"></div></div></div></div><div class="lyz-box-pick" > <div class="lyz-box-pick-click"  > <span class="lyz-box-pick-icon"></span><span class="lyz-box-pick-text">立即点击验证</span></div><div class="lyz-box-pick-tip" style=""><span >请将篮球移动到篮框里</span><img  class="lyz-box-pick-tip-img" src=""/></div><div class="lyz-pick-success-warp"  > <span class="lyz-pick-success-text">验证成功</span></div></div></div>';
            var $panel = null;

            $panel = SQ(panelHtml);
            var result = [];
            var sign_key = '';
            var begin_time = 0;
            var $imgWarp = $panel.find('.lyz-img-warp');
            var $imgBox = $panel.find('.lyz-img-box')
            var $move_img = $panel.find('.lyz-box-img-move');
            var $img = $panel.find('.lyz-box-img-bg');
            var $refresh = $panel.find('.lyz-box-refresh');
            var $box = $panel.find('.lyz-box-pick');
            var $loading = $panel.find('.lyz-box-loading');
            var $message = $panel.find('.lyz-box-message');
            var is_success = false;
            var _sid = '';
            $refresh.on('click', function () {
                if (is_success) {
                    return;
                }
                loadVerify();
            });

            function showMessage(success, msg) {
                $message.slideDown();
                $message.text(msg);
                if (success) {
                    $message.removeClass('lyz-box-message-error');
                } else {
                    $message.addClass('lyz-box-message-error');
                }
                setTimeout(function () {
                    $message.slideUp();
                }, 2000);
            }

            function onDrag(event, m) {
                // 鼠标移动时 取当前移动后的x、y的数据
                var x2 = event.pageX || (event.targetTouches && event.targetTouches[0].pageX);
                var y2 = event.pageY || (event.targetTouches && event.targetTouches[0].pageY);
                if (x2 === 0 || y2 === 0) {
                    return;
                }
                var left = (x2 - dragStartX) + leftStart;
                var top = (y2 - dragStartY) + topStart;
                if (left < -1) {
                    left = -1;
                    event.preventDefault();
                }
                if (left > 246) {
                    left = 246;
                    event.preventDefault();
                }
                $move_img.css({
                    left: left + "px",
                    top: top + 'px'
                });
            }

            var dragStartX;
            var dragStartY;
            var leftStart;
            var topStart;

            $move_img.on('touchstart dragstart', function (e) {
                if (is_success) return;
                // 鼠标按下后就要取到当前元素的x、y的位置数据
                dragStartX = e.pageX || (e.targetTouches && e.targetTouches[0].pageX);
                dragStartY = e.pageY || (e.targetTouches && e.targetTouches[0].pageY);
                leftStart = Number.parseInt($move_img.css('left').replace('px', ''));
                topStart = Number.parseInt($move_img.css('top').replace('px', ''));
                $box.addClass('lyz-moving')
                // 绑定一个鼠标移动的事件
                $move_img.on('touchmove drag', onDrag);
            });

            function mouseUp(event) {
                event.preventDefault();
                if (is_success) return;
                $move_img.off('touchmove drag');
                var time = new Date().getTime();
                var x = randomStr(32) + "" + ($move_img.position().left + $move_img.width() / 2);
                var y = randomStr(32) + "" + ($move_img.position().top + $move_img.height() / 2);
                var code = a(randomStr(32) + time, sign_key) + " " + a(x, sign_key) + " " + a(y, sign_key);
                var did = devid();
                var check = a(encodeURIComponent(JSON.stringify(config.checkParams())), did);
                check = randomStr(16) + check + randomStr(16);
                var params = {
                    _did: did,
                    _sid: _sid,
                    sense: config.sense,
                    verify_code: code,
                    verify_check: check
                };
                SQ.post(config.checkUrl, params, function (rs) {
                    $box.removeClass('lyz-moving');
                    rs._sid = _sid;
                    if (!rs.success) {
                        showMessage(false, rs.msg ? rs.msg : '验证失败,请重新操作');
                        if (config.fail) {
                            config.fail(rs);
                        }
                        loadVerify();

                    } else {
                        is_success = true;
                        showMessage(true, rs.msg ? rs.msg : ('恭喜你,验证成功'));
                        if (config.success) {
                            config.success(rs);
                        }
                        if (config.sense) {
                            localStorage.setItem('lyv_sense_token' + config.sense_scene, rs.token);
                        }
                        $box.addClass('lyz-move-success');
                        if (!config.container) {
                            setTimeout(function () {
                                $panel.fadeOut();
                                $model.fadeOut();
                            }, 1000);
                        }
                    }
                });
            }

            $move_img.on('touchend dragend', mouseUp);


            function loadVerify() {
                if (is_success) return;
                $loading.fadeIn();
                _sid = randomStr();
                var url = config.codeUrl;
                if (url.indexOf('?') === -1) {
                    url += "?";
                }
                url += "&_sid=" + _sid;
                SQ.get(url, function (rs) {
                    var code = rs.code;
                    var kv = code.split(' ');
                    sign_key = kv[0].substr(0, 16) + kv[1].substr(0, 16);
                    $img.attr('src', b(kv[0].substr(16), sign_key));
                    $move_img.attr('src', b(kv[1].substr(16), sign_key));
                    begin_time = new Date().getTime();
                    $loading.fadeOut();
                    $move_img.css({
                        left: 0,
                        top: Number.parseInt(Math.random() * 93) + 'px',
                    });
                });
            }


            if (config.container) {
                SQ(config.container).append($panel);
                if (config.hidePanel) {
                    $panel.addClass('lyz-box-trigger');
                    $panel.css({
                        width: '288px',
                        display: 'block',
                        position: 'relative',
                        border: 'none',
                        padding: 0
                    });
                    $imgBox.css({
                        position: 'absolute',
                        bottom: '40px',
                        'padding-bottom': '6px'
                    });
                } else {
                    $panel.css({
                        width: '308px',
                        display: 'block',
                        position: 'initial'
                    });
                }
                loadVerify();
            }else{
                $panel.addClass('lyz-box-pop');
            }
            return {
                reset: function () {
                    is_success = false;
                    $box.removeClass('lyz-move-success');
                    loadVerify();
                },
                show: function (el) {
                    if ($model.parent().length === 0) {
                        SQ(document.body).append($model);
                    }
                    if ($panel.parent().length === 0) {
                        SQ(document.body).append($panel);
                    }
                    if (el && window.innerWidth > 600) {
                        var $el = SQ(el);
                        var offset = $el.offset();
                        var top = offset.top-window.scrollY- 110;
                        var left = offset.left - 60;
                        if (top < 10) {
                            top = 10;
                        }
                        if (left < 10) {
                            left = 10;
                        }
                        if (left + 310 > window.innerWidth) {
                            left = window.innerWidth - 320;
                        }
                        $panel.css({
                            top: top+'px',
                            left: left+'px'
                        })
                    }
                    $panel.fadeIn();
                    $model.fadeIn();
                    loadVerify();
                },
                hide: function () {
                    $panel.fadeOut();
                    $model.fadeOut();
                    setTimeout(function () {
                        $panel.remove();
                        $model.remove();
                    }, 1000);
                }
            }
        },
        rotate: function (conf) {
            var config = {
                codeUrl: '/home/testcode',
                checkUrl: '/home/testcheck',
                senseUrl: '/home/senseCheck',
                sense: false,
                sense_scene: '',
                sense_ok: true,
                type: 'rotate',
                hidePanel: false,
                checkParams: function () {
                    return {}
                },
                fail: function (rs) {
                }, success: function (rs) {
                }
            }
            SQ.extend(config, conf);
            if (config.sense && config.sense_ok) {
                return intellisense(config);
            }
            var $model = SQ("<div class='ly-model-bg'></div>");
            $model.on('click', function () {
                $panel.fadeOut();
                $model.fadeOut();
            })
            var panelHtml = '<div class="lyz-box"><div class="lyz-img-box"><div class="lyz-img-warp" style="position: relative"><img class="lyz-box-img-bg"/><img class="lyz-box-rotate"/><div class="lyz-box-loading" style="display:none;"><div class="lyz-box-loading-icon"></div><span>加载中</span></div><div class="lyz-box-message">请按要求处理</div> <div class="lyz-box-tool"><div class="lyz-box-refresh"></div></div></div></div><div class="lyz-move-box"><div class="lyz-moved"></div><div class="lyz-move-ctrl" style="left: -1px"><span class="lyz-move-icon"></span></div><span class="lyz-move-text">向右拖动滑块将上图旋转正</span></div></div>';
            var $panel = null;

            $panel = SQ(panelHtml);
            var sign_key = '';
            var itemMd5 = '';
            var begin_time = 0;
            var $ctrl = $panel.find('.lyz-move-ctrl');
            var $imgBox = $panel.find('.lyz-img-box');
            var $moved = $panel.find('.lyz-moved');
            var $box = $panel.find('.lyz-move-box');
            var $item = $panel.find('.lyz-box-rotate');
            var $img = $panel.find('.lyz-box-img-bg');
            var $refresh = $panel.find('.lyz-box-refresh');
            var $loading = $panel.find('.lyz-box-loading');
            var $message = $panel.find('.lyz-box-message');
            var is_success = false;
            var _sid = '';
            $refresh.on('click', function () {
                if (is_success) {
                    return;
                }
                loadVerify();
            });

            function showMessage(success, msg) {
                $message.slideDown();
                $message.text(msg);
                if (success) {
                    $message.removeClass('lyz-box-message-error');
                } else {
                    $message.addClass('lyz-box-message-error');
                }
                setTimeout(function () {
                    $message.slideUp();
                }, 2000);
            }

            function mouseUp() {
                if (is_success) return;
                $box.off('touchmove mousemove');
                var time = new Date().getTime() + '';
                var rotate = $item.attr('angle');
                var code = a(itemMd5 + time + rotate + '', sign_key);
                var did = devid();
                var check = a(encodeURIComponent(JSON.stringify(config.checkParams())), did);
                check = randomStr(16) + check + randomStr(16);
                var params = {
                    _did: did,
                    _sid: _sid,
                    sense: config.sense,
                    verify_code: code,
                    verify_check: check
                };
                SQ.post(config.checkUrl, params, function (rs) {
                    rs._sid = _sid;
                    $box.removeClass('lyz-moving');
                    if (!rs.success) {
                        showMessage(false, rs.msg ? rs.msg : '验证失败,请重新操作');
                        if (config.fail) {
                            config.fail(rs);
                        }
                        var animTime = 500;
                        $box.addClass('lyz-move-error');
                        $ctrl.animate({left: "-1px"}, animTime);
                        $moved.animate({'width': '0'}, animTime);
                        $item.css({transform: "rotate(" + 0 + "deg)"});
                        $item.attr('angle', 0);
                        setTimeout(function () {
                            $box.removeClass('lyz-move-error');
                            loadVerify();
                            if(config.hidePanel&&config.container){
                                $imgBox.css({display:''});
                            }
                        }, animTime);
                    } else {
                        is_success = true;
                        showMessage(true, rs.msg ? rs.msg : ('恭喜你,验证成功'));
                        if (config.success) {
                            config.success(rs);
                        }
                        if (config.sense) {
                            localStorage.setItem('lyv_sense_token' + config.sense_scene, rs.token);
                        }
                        $box.addClass('lyz-move-success');
                        if (!config.container) {
                            setTimeout(function () {
                                $panel.fadeOut();
                                $model.fadeOut();
                            }, 1000);
                        }
                    }
                });
            }

            function loadVerify() {
                if (is_success) return;
                $loading.fadeIn();
                _sid = randomStr();
                var url = config.codeUrl;
                if (url.indexOf('?') === -1) {
                    url += "?";
                }
                url += "&_sid=" + _sid;
                SQ.get(url, function (rs) {
                    var code = rs.code;
                    var kv = code.split(' ');
                    sign_key = kv[0].substr(0, 16) + kv[1].substr(0, 16);
                    $img.attr('src', b(kv[0].substr(16), sign_key));
                    $item.attr('src', b(kv[1].substr(16), sign_key));
                    var y = kv[2].substr(32);
                    itemMd5 = kv[2].substr(0, 32);
                    begin_time = new Date().getTime();
                    $loading.fadeOut();
                });
            }


            $ctrl.on('touchstart mousedown', function (e) {
                if (is_success) return;
                // 鼠标按下后就要取到当前元素的x、y的位置数据
                var x = e.pageX || e.targetTouches[0].pageX;
                // 取到了x和y的坐标对象
                var divx = $ctrl.position().left;
                $box.addClass('lyz-moving');
                if(config.hidePanel&&config.container){
                    $imgBox.show();
                }
                // 绑定一个鼠标移动的事件
                $box.on('touchmove mousemove', function (event) {
                    // 鼠标移动时 取当前移动后的x、y的数据
                    var x2 = event.pageX || event.targetTouches[0].pageX;
                    var left = divx + (x2 - x);
                    if (left < -1) {
                        left = -1;
                    }
                    if (left > 246) {
                        left = 246;
                    }
                    var rotate = left * 2 / 246 * 360;
                    $item.css({transform: "rotate(" + rotate + "deg)"});
                    $item.attr('angle', rotate);
                    $moved.css('width', (left + 1) + 'px')
                    $ctrl.css({
                        left: left + "px"
                    });
                });
            });
            $ctrl.on('touchend mouseup', mouseUp);


            if (config.container) {
                SQ(config.container).append($panel);
                if (config.hidePanel) {
                    $panel.addClass('lyz-box-trigger');
                    $panel.css({
                        width: '288px',
                        display: 'block',
                        position: 'relative',
                        border: 'none',
                        padding: 0
                    });
                    $imgBox.css({
                        position: 'absolute',
                        bottom: '40px',
                        'padding-bottom': '6px'
                    });
                } else {
                    $panel.css({
                        width: '308px',
                        display: 'block',
                        position: 'initial'
                    });
                }
                loadVerify();
            }else{
                $panel.addClass('lyz-box-pop');
            }
            return {
                reset: function () {
                    is_success = false;
                    $box.removeClass('lyz-move-success');
                    $ctrl.css({left: "-1px"});
                    $moved.css({'width': '0'});
                    loadVerify();
                },
                show: function (el) {
                    if ($model.parent().length === 0) {
                        SQ(document.body).append($model);
                    }
                    if ($panel.parent().length === 0) {
                        SQ(document.body).append($panel);
                    }
                    if (el && window.innerWidth > 600) {
                        var $el = SQ(el);
                        var offset = $el.offset();
                        var top = offset.top-window.scrollY- 110;
                        var left = offset.left - 60;
                        if (top < 10) {
                            top = 10;
                        }
                        if (left < 10) {
                            left = 10;
                        }
                        if (left + 310 > window.innerWidth) {
                            left = window.innerWidth - 320;
                        }
                        $panel.css({
                            top: top+'px',
                            left: left+'px'
                        })
                    }
                    $panel.fadeIn();
                    $model.fadeIn();
                    loadVerify();
                },
                hide: function () {
                    $panel.fadeOut();
                    $model.fadeOut();
                    setTimeout(function () {
                        $panel.remove();
                        $model.remove();
                    }, 1000);
                }
            }
        },
    }

    function intellisense(config) {
        var verifyPanel = null;
        if (config.container) {
            var html = '<div class="lyz-intellisense  "><div class="lyz-intellisense-wait"><span class="lyz-intellisense-status-icon" ></span><div class="lyz-intellisense-wait-icon-warp"><span class="lyz-intellisense-wait-icon" ></span><div class="lyz-intellisense-ball-scale"><div></div> <div></div> <div></div></div></div><span class="lyz-intellisense-text">点击完成验证</span></div></div>';
            var $intellisense = SQ(html);
            var text = $intellisense.find('.lyz-intellisense-text');
            var is_success=false;
            $intellisense.on('click', function () {
                if(is_success)return;
                $intellisense.addClass('lyz-intellisense--check');
                text.text('安全检测中...');
                var token = localStorage.getItem('lyv_sense_token' + config.sense_scene);
                var did = devid();

                function senseFail(time) {
                    setTimeout(function () {
                        $intellisense.remove();
                        config.sense_ok = false;
                        verifyPanel = LyVerify[config.type](config);
                    }, time);
                }

                if (!token) {
                    senseFail(500);
                    return;
                }
                var check = a(encodeURIComponent(JSON.stringify(config.checkParams())), did);
                check = randomStr(16) + check + randomStr(16);
                var params = {
                    token: token,
                    _did: did,
                    verify_check: check
                }
                var begin_time = new Date().getTime();
                SQ.post(config.senseUrl, params, function (rs) {
                    var time = 500 - (new Date().getTime() - begin_time);
                    if (time < 0) {
                        time = 0;
                    }
                    if (rs.success) {
                        localStorage.setItem('lyv_sense_token' + config.sense_scene, rs.token);
                        if (config.success) {
                            config.success(rs);
                        }
                        setTimeout(function () {
                            $intellisense.removeClass('lyz-intellisense--check');
                            $intellisense.addClass('lyz-intellisense--success');
                            text.text('验证成功');
                            is_success=true;
                        }, time);
                    } else {
                        senseFail(time);
                    }
                });
            });
            SQ(config.container).append($intellisense);
            return {
                show: function () {
                },
                hide: function () {
                    if (verifyPanel) {
                        verifyPanel.hide();
                    }
                },
                reset: function () {
                    if (verifyPanel) {
                        verifyPanel.reset();
                    }
                }
            }
        } else {
            return {
                show: function (el) {
                    if (verifyPanel) {
                        return verifyPanel.show(el);
                    }
                    var token = localStorage.getItem('lyv_sense_token' + config.sense_scene);
                    var did = devid();

                    function senseFail(time) {
                        config.sense_ok = false;
                        verifyPanel = LyVerify[config.type](config).show(el);
                    }

                    if (!token) {
                        senseFail(500);
                        return;
                    }
                    var check = a(encodeURIComponent(JSON.stringify(config.checkParams())), did);
                    check = randomStr(16) + check + randomStr(16);
                    var params = {
                        token: token,
                        _did: did,
                        verify_check: check
                    }
                    var begin_time = new Date().getTime();
                    SQ.post(config.senseUrl, params, function (rs) {
                        var time = 500 - (new Date().getTime() - begin_time);
                        if (time < 0) {
                            time = 0;
                        }
                        if (rs.success) {
                            localStorage.setItem('lyv_sense_token' + config.sense_scene, rs.token);
                            if (config.success) {
                                config.success(rs);
                            }
                        } else {
                            senseFail(time);
                        }
                    });
                },
                hide: function () {
                    if (verifyPanel) {
                        verifyPanel.hide();
                    }
                },
                reset: function () {
                    if (verifyPanel) {
                        verifyPanel.reset();
                    }
                },
            }

        }
    }

    function devid() {
        if (!localStorage) {
            return randomStr(32);
        } else {
            var did = localStorage.getItem('ly_verify_did');
            if (!did) {
                did = randomStr(32);
                localStorage.setItem('ly_verify_did', did);
            }
            return did;
        }
    }

    function randomStr(len, radix) {
        var chars = (new Date().getTime() + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz').split('');
        var uuid = [], i;
        radix = radix || chars.length;
        if (len) {
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
        } else {
            var r;
            for (i = 0; i < 32; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random() * 16;
                    uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
                }
            }
        }
        return uuid.join('');
    }

    function a(str, sign_key) {
        var sign_b = c(sign_key);
        var str_b = c(str);
        var b = [];
        for (var i = 0; i < str_b.length; i++) {
            var k = str_b[i] ^ sign_b[i % sign_b.length];
            b.push(k);
        }
        return window.btoa(d(b));
    }

    function b(str, sign_key) {
        str = window.atob(str);
        var sign_b = c(sign_key);
        var str_b = c(str);
        var b = [];
        for (var i = 0; i < str_b.length; i++) {
            var k = str_b[i] ^ sign_b[i % sign_b.length];
            b.push(k);
        }
        return d(b);
    }


    function c(str) {
        var bytes = [];
        var len, c;
        len = str.length;
        for (var i = 0; i < len; i++) {
            c = str.charCodeAt(i);
            if (c >= 0x010000 && c <= 0x10FFFF) {
                bytes.push(((c >> 18) & 0x07) | 0xF0);
                bytes.push(((c >> 12) & 0x3F) | 0x80);
                bytes.push(((c >> 6) & 0x3F) | 0x80);
                bytes.push((c & 0x3F) | 0x80);
            } else if (c >= 0x000800 && c <= 0x00FFFF) {
                bytes.push(((c >> 12) & 0x0F) | 0xE0);
                bytes.push(((c >> 6) & 0x3F) | 0x80);
                bytes.push((c & 0x3F) | 0x80);
            } else if (c >= 0x000080 && c <= 0x0007FF) {
                bytes.push(((c >> 6) & 0x1F) | 0xC0);
                bytes.push((c & 0x3F) | 0x80);
            } else {
                bytes.push(c & 0xFF);
            }
        }
        return bytes;
    }

    function d(arr) {
        if (typeof arr === 'string') {
            return arr;
        }
        var str = '',
            _arr = arr;
        for (var i = 0; i < _arr.length; i++) {
            var one = _arr[i].toString(2),
                v = one.match(/^1+?(?=0)/);
            if (v && one.length === 8) {
                var bytesLength = v[0].length;
                var store = _arr[i].toString(2).slice(7 - bytesLength);
                for (var st = 1; st < bytesLength; st++) {
                    store += _arr[st + i].toString(2).slice(2);
                }
                str += String.fromCharCode(parseInt(store, 2));
                i += bytesLength - 1;
            } else {
                str += String.fromCharCode(_arr[i]);
            }
        }
        return str;
    }

    return LyVerify;
});